package server

import (
	"devops-tools/config"
	"fmt"
	"github.com/shirou/gopsutil/v3/mem"
	"github.com/sirupsen/logrus"
	"net"
	"os/exec"
	"strings"
	"time"
)

var ip = "127.0.0.1"

func PortMonitory() {
	logrus.Println("*******启动端口监控*******")
	ports := config.GetConfig().Portmonitor.Ports
	startCommand := config.GetConfig().Portmonitor.StartCommand
	logrus.Println("监控的端口为：", ports)
	if ports == nil {
		logrus.Println("未配置端口，请检查配置文件")
		return
	}
	//定时任务
	ticker := time.NewTicker(time.Second * time.Duration(config.GetConfig().Portmonitor.PollSecond))
	defer ticker.Stop()
	//无限循环
	for range ticker.C {
		GetFreeMemory()
		index := 0
		for _, p := range ports {
			sh := startCommand[index]
			monitor(p, sh)
			index++
		}
	}
}

//启动服务
func StartServer(port int) {
	ports := config.GetConfig().Portmonitor.Ports
	startCommand := config.GetConfig().Portmonitor.StartCommand
	index := 0
	for _, p := range ports {
		if p == port {
			sh := startCommand[index]
			monitor(p, sh)
			break
		}
	}
}

func monitor(port int, sh string) {
	logrus.Printf("检查端口:%d", port)
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", ip, port))
	if err != nil {
		logrus.Println("未启动")
		logrus.Println("执行启动脚本: sh ", sh)
		// 端口不存在，执行启动脚本
		cmd := exec.Command("sh")
		command := strings.Split(sh, " ")
		cmd.Args = append(cmd.Args, command...)
		err = cmd.Run()
		if err != nil {
			execWebHook(fmt.Sprintf("端口[%d]没有正常运行，执行启动命令，仍然启动失败", port))
			logrus.Println("启动脚本执行失败:", err)
		} else {
			execWebHook(fmt.Sprintf("端口[%d]没有正常运行，执行启动命令后恢复正常", port))
			logrus.Println("启动脚本执行成功")
		}
	} else {
		logrus.Println("运行中")
		// 端口存在，关闭连接
		conn.Close()
	}
}

func execWebHook(msg string) {
	msg = strings.Replace(config.GetConfig().Alarm.NoticeTemplate, "{notice_msg}", msg, 1)
	go WebHook(msg)
}

func GetFreeMemory() string {
	memInfo, e := mem.VirtualMemory()
	if e != nil {
		logrus.Println("读取内存信息错误：", e)
	}
	//获取总内存大小，单位GB
	memTotal := memInfo.Total / 1024 / 1024 / 1024
	//获取已使用内存，单位MB
	memUsed := memInfo.Used / 1024 / 1024
	//可用内存大小
	memAva := memInfo.Available / 1024 / 1024
	//内存可用率
	memUsedPercent := memInfo.UsedPercent
	result := fmt.Sprintf("总内存：%vGB,已用内存：%vMB，可用内存：%vMB ,内存使用率：%3.f%%", memTotal, memUsed, memAva, memUsedPercent)
	logrus.Printf(result)
	return result
}
